package camid.main.jmeter;

import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.util.ShutdownClient;

import camid.distribution.activeobject.ProxyExecutorManager;
import camid.main.ClientFacade;
import camid.test.testobjects.DelayObject;
import camid.test.testobjects.IDelayObject;


public class CamidJMeterClient extends AbstractJavaSamplerClient {

	public static final Long DEFAULT_DELAY = 100L;
	public static final String DEFAULT_NSHOST = "127.0.0.1";
	public static final Integer DEFAULT_NSPORT = 15001;
	private static final String DEFAULT_OBJECT = DelayObject.class.getCanonicalName();

	private String nshost;
	private Integer nsport;
	private Long delay;
	private String object;

	private static AtomicInteger objectCounter = new AtomicInteger(0);

	private IDelayObject delayObject;

	@Override
	public SampleResult runTest(JavaSamplerContext samplerContext) {
		SampleResult result = new SampleResult();

		try
		{
			result.sampleStart();
			delayObject.doDelay(delay);
			result.setSuccessful(true);
		}
		catch(Exception e)
		{
			result.setSuccessful(false);
		}
		finally
		{
			result.sampleEnd();
		}

		return result;
	}

	private String whoAmI() {
		StringBuilder sb = new StringBuilder();
		sb.append(Thread.currentThread().toString());
		sb.append("@");
		sb.append(Integer.toHexString(hashCode()));
		return sb.toString();
	}

	@Override
	public Arguments getDefaultParameters() {
		Arguments params = new Arguments();
		params.addArgument("object", String.valueOf(DEFAULT_OBJECT));
		params.addArgument("delay", String.valueOf(DEFAULT_DELAY));
		return params;
	}

	public void setupTest(JavaSamplerContext context) {
		getLogger().debug(whoAmI() + "\tsetupTest()");
		listParameters(context);

		EnviromentVariableHandler handler = EnviromentVariableHandler.getInstance();

		nshost = handler.getMainNode() != null ? handler.getMainNode() : DEFAULT_NSHOST;
		nsport = handler.getPort() != null ? handler.getPort() : DEFAULT_NSPORT;
		
		delay = context.getLongParameter("delay", DEFAULT_DELAY);
		object = context.getParameter("object", DEFAULT_OBJECT);

		ClientFacade client = ClientFacade.getInstance();
		client.remoteNameService(nshost, nsport);
		try {
			Class<?> remoteClass = Class.forName(object);
			while(delayObject == null)
			{
				delayObject = client.lookupObject(IDelayObject.class, remoteClass);
				if(delayObject == null)
				{
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	public void teardownTest(JavaSamplerContext context) 
	{
		getLogger().debug(whoAmI() + "\tteardownTest()");
		super.teardownTest(context);
		ProxyExecutorManager.getInstance().shutdownExecutors();
		ClientFacade.getInstance().shutdownSenderQueue();
	}
	

	private void listParameters(JavaSamplerContext context) 
	{
		if (getLogger().isDebugEnabled()) {
			Iterator<String> argsIt = context.getParameterNamesIterator();
			while (argsIt.hasNext())
			{
				String name = argsIt.next();
				getLogger().debug(name + "=" + context.getParameter(name));
			}
		}
	}
	
	

}
